package ru.sgu.diploma.practic.domain.model;

import ru.sgu.diploma.practic.errors.NoRuleForInputException;
import ru.sgu.diploma.practic.errors.NoStateFoundForNameException;
import ru.sgu.diploma.practic.errors.TranslateException;
import ru.sgu.diploma.practic.service.TranslateFunction;

import java.util.*;

/**
 * User: datmakin
 * Date: 13.03.11
 * Email: atmakin.dv@gmail.com
 */
public class Automat  {
    private Map<String, State> stateMap = new HashMap<String, State>();
    private State presentState;
    private String[] alphabet;

    public Automat() {
    }

    public void setStartState(String stateName) throws NoStateFoundForNameException {
        if (!stateMap.containsKey(stateName))
            throw new NoStateFoundForNameException(stateName);
        this.presentState = stateMap.get(stateName);
    }

    public String[] translate(String[] input) throws TranslateException {

        String[] output = new String[input.length];
        try {
            for (int i = 0; i < input.length; i++)
                output[i] = (process(input[i]));
        } catch (NoStateFoundForNameException e) {
            throw new TranslateException("NoStateFound for: " + e.getMessage());
        } catch (NoRuleForInputException e) {
            throw new TranslateException("NoRuleFound for: " + e.getMessage());
        }
        return output;
    }

    public String process(String input) throws NoRuleForInputException, NoStateFoundForNameException {
        String result = presentState.getOutputForInput(input);
        String nextStateName = presentState.getNextStateNameForInput(input);
        if (!stateMap.containsKey(nextStateName))
            throw new NoStateFoundForNameException(nextStateName);
        this.presentState = stateMap.get(nextStateName);
        return result;
    }

    public Map<String, State> getStateMap() {
        return stateMap;
    }

    public void setStateMap(Map<String, State> stateMap) {
        this.stateMap = stateMap;
    }

    public State getPresentState() {
        return presentState;
    }

    public void setPresentState(State presentState) {
        this.presentState = presentState;
    }

    public String[] getAlphabet() {
        return alphabet;
    }

    public void setAlphabet(String[] alphabet) {
        this.alphabet = alphabet;
    }
}
